package com.dhecp.project.logstics.service.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;


import com.alibaba.fastjson.JSON;
import com.dhecp.common.core.domain.AjaxResult;
import com.dhecp.common.utils.MessageUtils;
import com.dhecp.common.utils.RandomValueUtils;
import com.dhecp.core.constant.DataFiltering;
import com.dhecp.core.utils.PageUtils;
import com.dhecp.framework.util.ShiroUtils;
import com.dhecp.project.base.domain.LogsticsServer;
import com.dhecp.project.base.mapper.LogsticsServerMapper;
import com.dhecp.project.business.domain.*;
import com.dhecp.project.business.mapper.*;
import com.dhecp.project.common.domain.ModuleNidAndBid;
import com.dhecp.project.common.mapper.ModuleNidAndBidMapper;
import com.dhecp.project.common.service.ModuleNidAndBidService;
import com.dhecp.project.common.service.impl.BaseModuleServiceImpl;
import com.dhecp.project.finance.domain.AccountCountForCompany;
import com.dhecp.project.finance.domain.AccountDetailedForCompany;
import com.dhecp.project.finance.mapper.AccountCountForCompanyMapper;
import com.dhecp.project.finance.mapper.AccountDetailedForCompanyMapper;
import com.dhecp.project.logstics.domain.FbaBox;
import com.dhecp.project.logstics.domain.FbaSpellTicket;
import com.dhecp.project.logstics.domain.FbaSpellTicketDetail;
import com.dhecp.project.logstics.mapper.*;
import com.dhecp.project.logstics.service.FbaSpellTicketService;
import com.dhecp.project.system.domain.SysAccountBandDept;
import com.dhecp.project.system.mapper.SysAccountBandDeptMapper;
import com.dhecp.project.system.service.SysDictionaryForFieldService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 物流拼票 服务层
 * @Author fxz
 * @Date 2022/10/23
 */
@Service
public class FbaSpellTicketServicelmpl extends BaseModuleServiceImpl implements FbaSpellTicketService {

    @Autowired
    private SysDictionaryForFieldService dictionaryForFieldService;
    @Autowired
    private FbaSpellTickMapper fbaSpellTickMapper;
    @Autowired
    private ModuleNidAndBidService moduleNidAndBidService;
    @Autowired
    private FbaLogsticsOrderMapper fbaLogsticsOrderMapper;
    @Autowired
    private FbaLogsticsOrderDetailMapper fbaLogsticsOrderDetailMapper;
    @Autowired
    private FbaSpellTicketDetailMapper fbaSpellTicketDetailMapper;

    @Autowired
    private LogsticsPatternMapper logsticsPatternMapper;

    @Autowired
    private LogsticsPatternDetailsMapper logsticsPatternDetailsMapper;

    @Autowired
    private LogsticsMmodeGradsMapper logsticsMmodeGradsMapper;

    @Autowired
    private ModuleNidAndBidMapper moduleNidAndBidMapper;

    @Autowired
    private LogsticsServerMapper logsticsServerMapper;

    @Autowired
    private FbaLogsticsOrderBoxMapper fbaLogsticsOrderBoxMapper;

    @Autowired
    private FbaBoxMapper fbaBoxMapper;

    @Autowired
    private ProductBasisMapper productBasisMapper;

    @Autowired
    private SysAccountBandDeptMapper sysAccountBandDeptMapper;

    @Autowired
    private AccountCountForCompanyMapper accountCountForCompanyMapper;

    @Autowired
    private AccountDetailedForCompanyMapper businessMapper;

    /**
     * 查询拼票单
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public List<FbaSpellTicket> queryList(Map<String, Object> params) throws Exception {
        params.put(DataFiltering.TABLE_ALIAS, "t1");	//查询表别名
        params.put(DataFiltering.DATA_WHERE, dictionaryForFieldService.getWhereStr(params));	//常规查询条件SQL语句
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));	//数据权限查询条件SQL语句

        if (params.get("field") == null || params.get("field") == ""){
            String orderBy = "createTime DESC";
            PageUtils.startPageOrder(orderBy);
        }else{
            PageUtils.startPage();
        }

        return fbaSpellTickMapper.select(params);
    }

    /**
     *@Description: 拼票动作
     *@date: 2022-10-09 10:11
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult updateSpellTicket(Map<String, Object> params) {
        //TODO 这里的拼票标识生产规则未知 是否根据code的生成方式来生成
        List<FbaSpellTicket> fbaSpellTicketList =  JSON.parseArray(params.get("infoItems").toString(), FbaSpellTicket.class);
        Long data = new Date().getTime();
        for (FbaSpellTicket item : fbaSpellTicketList){
            item.setUpdateTime(new Date());
            item.setSpellTicketState("1");//拼票状态
            item.setUpdateUser(ShiroUtils.getUserId());
//            item.setCodeSpellTicket(data.toString());
            fbaSpellTickMapper.update(item);
        }
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }

    /**
     *@Description: 拼票解除动作
     *@date: 2022-10-09 10:11
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult cancelSpellTicket(Map<String, Object> params) {
        List<FbaSpellTicket> fbaSpellTicketList =  JSON.parseArray(params.get("infoItems").toString(), FbaSpellTicket.class);
        for (FbaSpellTicket item : fbaSpellTicketList){
            item.setUpdateTime(new Date());
            item.setSpellTicketState("0");//未拼票状态
            item.setUpdateUser(ShiroUtils.getUserId());
//            item.setCodeSpellTicket("");
            fbaSpellTickMapper.update(item);
            //TODO 未完成根据选择的数据 查询出对应平单的数据进行统一拼票解除
        }
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }

    /**
     * 删除数据
     * @param
     * @return
     * @author fxz
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult delete(Map<String, Object> params) {
        List<FbaSpellTicket> fbaSpellTicketList = JSON.parseArray(params.get("infoItems").toString(), FbaSpellTicket.class);
        if (fbaSpellTicketList == null || fbaSpellTicketList.size() == 0) {
            return AjaxResult.error(MessageUtils.message("module.error.jsontoentyerror"));
        }
        for (FbaSpellTicket fbaSpellTicket : fbaSpellTicketList) {
            fbaSpellTickMapper.delete(fbaSpellTicket);
            //TODO 未完善 是否需要做其他的操作 比如返回发货单界面
        }
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }

    /**
     *@Description: 审核
     *@Author: fxz
     *@date: 2022-10-09 10:11
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult updateState(Map<String, Object> params) {
        //传入的拼票数据
        List<FbaSpellTicket> fbaSpellTicketList =  JSON.parseArray(params.get("infoItems").toString(), FbaSpellTicket.class);
        List<FbaSpellTicket> fbaSpellTicketListNew = new ArrayList<>();
        List<FbaLogsticsOrderDetail> fbaLogsticsOrderDetailList = new ArrayList<>();
        List<FbaLogsticsOrder> fbaLogsticsOrderList = new ArrayList<>();
        FbaLogsticsOrderDetail fbaLogsticsOrderDetail;
        for (FbaSpellTicket item:fbaSpellTicketList) {
            Map<String, Object> params1 = new HashMap<String, Object>();
            params1.put("moduleTable","TP_FbaLogsticsOrder");
            ModuleNidAndBid moduleNidAndBid = moduleNidAndBidService.queryModuleNidAndBidInitial(params1);
            //新增物流订单信息
            FbaLogsticsOrder fbaLogsticsOrder = new FbaLogsticsOrder();
            fbaLogsticsOrder.setCode(moduleNidAndBid.getBid());
            fbaLogsticsOrder.setBid(moduleNidAndBid.getBid());
            fbaLogsticsOrder.setNid(moduleNidAndBid.getNid());

//            params1.put("codeSpellTicket", item.getCodeSpellTicket());
            //查询需要操作的拼票数据
            fbaSpellTicketListNew = fbaSpellTickMapper.findFbaSpellTicket(params1);
            for (FbaSpellTicket fbaSpellTicket : fbaSpellTicketListNew){
                //修改拼票单状态
                fbaSpellTicket.setUpdateTime(new Date());
                fbaSpellTicket.setState(params.get("state").toString());
                fbaSpellTicket.setAuditTime(new Date());
                fbaSpellTicket.setAuditUser(ShiroUtils.getUserId());
                fbaSpellTickMapper.update(fbaSpellTicket);

                //TODO 新增物流订单明细  未完善分账的逻辑
                fbaLogsticsOrderDetail = new FbaLogsticsOrderDetail();

                fbaLogsticsOrderDetailList.add(fbaLogsticsOrderDetail);
            }
            //新增物流订单
            fbaLogsticsOrderMapper.insertFbaLogsticsOrder(fbaLogsticsOrder);

//            fbaLogsticsOrderDetailMapper.insertBatchOrderDetail(fbaLogsticsOrderDetailList);
        }

        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }

    /**
     *@Description:回退
     *@Author: fxz
     *@date: 2022-10-09 10:11
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult spellTicketState(Map<String, Object> params) {
        //传入的物流下单数据
        List<FbaLogsticsOrder> fbaLogsticsOrderList =  JSON.parseArray(params.get("infoItems").toString(), FbaLogsticsOrder.class);
        FbaSpellTicket fbaSpellTicket;
        for (FbaLogsticsOrder fbaLogsticsOrder : fbaLogsticsOrderList){
            //删除物流下单明细
            FbaLogsticsOrderDetail detail = new FbaLogsticsOrderDetail();
            detail.setCodeFbaLogsticsOrder(fbaLogsticsOrder.getCode());
            fbaLogsticsOrderDetailMapper.delete(detail);

            //删除物流下单
            fbaLogsticsOrderMapper.delete(fbaLogsticsOrder);

            //TODO 未将拼票表中的状态修改为未审核 下单明细中需要添加一个拼票对应的饿主键guid
//            fbaSpellTicket = new FbaSpellTicket();
//            fbaSpellTicket.setUpdateTime(new Date());
//            fbaSpellTicket.setState(params.get("state").toString());
//            fbaSpellTicket.setAuditTime(new Date());
//            fbaSpellTicket.setAuditUser(ShiroUtils.getUserId());
//            fbaSpellTickMapper.update(fbaSpellTicket);
        }


        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }

    /**
     * 查询单条
     * @param params
     * @return
     */
    @Override
    public FbaSpellTicket queryFirstByGuid(String guid) {
        return fbaSpellTickMapper.queryFirstByGuid(guid);
    }


    /**
     * 查询拼票单合并
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public List<FbaSpellTicket> queryListMerge(Map<String, Object> params) {
        String guidList = String.valueOf(params.get("guidList"));
        String[] guidListSplit = guidList.split(",");
        params.put("guidListSplit",guidListSplit);
        List<FbaSpellTicket> fbaSpellTicketList = fbaSpellTickMapper.select(params);

        //根据主表的guid查询对应箱子所以信息
        List<FbaSpellTicketDetail> fbaSpellTicketDetail = fbaSpellTicketDetailMapper.findFbaSpellTicketDetail(params);

        Map<String, Object> params1 = new HashMap<String, Object>();
        params1.put("guid",params.get("guidLogsticsPattern"));
        //查询物流名称对应的数据
        LogsticsPattern logsticsPattern = logsticsPatternMapper.queryFirstByGuid(params1);

        //获取物流名称详情
        Map<String, Object> params2 = new HashMap<String, Object>();
        params2.put("code",logsticsPattern.getCode());
        params2.put("logisticsMmodeGuid",logsticsPattern.getGuid());
        List<LogsticsPatternDetails> textureList = logsticsPatternDetailsMapper.findLogsticsPatternDetails(params2);
        //获取物流方式梯度
        List<LogisticsMmodeGrads> logisticsMmodeGradList = logsticsMmodeGradsMapper.findLogisticsMmodeGrads(params2);
        List<LogisticsMmodeGrads> logisticsMmodeGrads  = logisticsMmodeGradList.stream().filter(logisticsMmodeGrads1 ->
                "WLMC".equals(logisticsMmodeGrads1.getType())).collect(Collectors.toList());


        List<FbaSpellTicketDetail> fbaSpellTicketDetailNew;
        List<FbaSpellTicketDetail> fbaSpellTicketDetailOld;
        BigDecimal weightVolNew;
        //最大的材质值
        BigDecimal texture = BigDecimal.ZERO;
        //最大材质名称
        String surchargeMaterialMax = "";
        //品名数量
        Set<String> gradeNum = new HashSet<>();
        //品名总计相加
        Integer pMNum = 0;
        //品名材质
        Set<String> gradeNumNew = new HashSet<>();
        List<LogisticsMmodeGrads> tdjzPrice;
        BigDecimal weightPrice;
        Integer num;
        //物流总费用
        BigDecimal actualLogisticsFreightTolOld = BigDecimal.ZERO;
        //计重费
        BigDecimal priceTranCalWeightPredictTolOld = BigDecimal.ZERO;
        BigDecimal priceQualityExtraPredictTolOld = BigDecimal.ZERO;
        BigDecimal priceProNameExtraPredictTolOld = BigDecimal.ZERO;
        BigDecimal priceClearanceOpeTolOld = BigDecimal.ZERO;
        //计重
        BigDecimal weightCal = BigDecimal.ZERO;
        //抛重
        BigDecimal weightVol = BigDecimal.ZERO;
        //实重
        BigDecimal weightReal = BigDecimal.ZERO;
        //计重总计
        BigDecimal weightCalTol = BigDecimal.ZERO;
        //抛重总计
        BigDecimal weightVolTol = BigDecimal.ZERO;
        //实重总计
        BigDecimal weightRealTol = BigDecimal.ZERO;
        //箱数
        Integer numBox = 0;
        FbaSpellTicket fbaSpellTicketNew = new FbaSpellTicket();
        //重新计算每个fba箱子数据
        for (FbaSpellTicket fbaSpellTicket : fbaSpellTicketList){
            //将旧的金额计算
            actualLogisticsFreightTolOld = actualLogisticsFreightTolOld.add(fbaSpellTicket.getActualLogisticsFreight());
            priceTranCalWeightPredictTolOld = priceTranCalWeightPredictTolOld.add(fbaSpellTicket.getPriceTranCalWeightPredict());
            priceQualityExtraPredictTolOld = priceQualityExtraPredictTolOld.add(fbaSpellTicket.getPriceQualityExtraPredict());
            priceProNameExtraPredictTolOld = priceProNameExtraPredictTolOld.add(fbaSpellTicket.getPriceProNameExtraPredict());
            priceClearanceOpeTolOld = priceClearanceOpeTolOld.add(fbaSpellTicket.getPriceClearanceOpe());
            numBox = numBox + fbaSpellTicket.getNumBox();
            weightRealTol = weightRealTol.add(fbaSpellTicket.getWeightReal());
            weightCalTol = weightCalTol.add(fbaSpellTicket.getWeightCal());
            weightVolTol = weightVolTol.add(fbaSpellTicket.getWeightVol());
            pMNum = pMNum + fbaSpellTicket.getNumProName();


            fbaSpellTicketDetailNew = fbaSpellTicketDetail.stream().filter(fbaSpellTicketDeta -> fbaSpellTicketDeta.getFbaSpellTicketGuid().equals(fbaSpellTicket.getGuid())).collect(Collectors.toList());
            //实际的商品信息
            fbaSpellTicketDetailOld = JSON.parseArray(fbaSpellTicketDetailNew.get(0).getProductInfo(), FbaSpellTicketDetail.class);
            //计算材质最大值
            for (FbaSpellTicketDetail fbaSpellTicketDetail1 : fbaSpellTicketDetailOld){
                String join = fbaSpellTicketDetail1.getNameGoodsCn() + '-' + fbaSpellTicketDetail1.getCodeGoodsHs() + '-' +fbaSpellTicketDetail1.getNameMaterialCn();
                gradeNum.add(join);
                gradeNumNew.add(fbaSpellTicketDetail1.getNameMaterialCn());

                //判断是否是混合材质
                if (fbaSpellTicketDetail1.getNameMaterialCn().indexOf(",") == -1) {
                    //赋值材质附加费(取最大值)
                    for (int j = 0; j < textureList.size(); j++) {
                        if (textureList.get(j).getMaterialName().equals(fbaSpellTicketDetail1.getNameMaterialCn())) {
                            if (textureList.get(j).getMaterialCost().compareTo(texture) > 0) {
                                texture = (textureList.get(j).getMaterialCost());
                                surchargeMaterialMax = (textureList.get(j).getMaterialName());
                            }
                        }
                    }
                } else {
                    String[] nameMaterialCnList = fbaSpellTicketDetail1.getNameMaterialCn().split(",");
                    for (String nameMaterialCn : nameMaterialCnList){
                        for (int j = 0; j < textureList.size(); j++) {
                            if (textureList.get(j).getMaterialName().equals(nameMaterialCn)) {
                                if (textureList.get(j).getMaterialCost().compareTo(texture) > 0) {
                                    texture = (textureList.get(j).getMaterialCost());
                                    surchargeMaterialMax = (textureList.get(j).getMaterialName());
                                }
                            }
                        }
                    }
                }
            }
            //计算商品实重和抛重
            for (FbaSpellTicketDetail fbaSpellTicketDetail1 : fbaSpellTicketDetailNew){
                weightVolNew = (new BigDecimal(fbaSpellTicketDetail1.getWidth()).multiply(new BigDecimal(fbaSpellTicketDetail1.getLength())
                        .multiply(new BigDecimal(fbaSpellTicketDetail1.getHeight())))).divide(new BigDecimal(logsticsPattern.getCoefficientWeight()), 2, RoundingMode.HALF_UP);
                weightReal = weightReal.add(new BigDecimal(fbaSpellTicketDetail1.getWeight()));
                //实际计重=MAX(单箱实重，单箱起重)之和
                weightCal = weightCal.add((new BigDecimal(fbaSpellTicketDetail1.getWeight()).max(logsticsPattern.getWeightCalBySingle())));
                weightVol = weightVol.add(weightVolNew);
            }
            //清除抛货信息
            fbaSpellTicket.setJettisonCoe(null);
        }

        //超出品名=实际品名-实际免费品名数
        num = gradeNum.size()-logsticsPattern.getNumFreeProName();
        //实际计重 =  max(A1，抛重之和)进行约分
        fbaSpellTicketNew.setWeightCal(precision(weightCal.max(weightVol)));
        //抛重
        fbaSpellTicketNew.setWeightVol(weightVol);
        //实重
        fbaSpellTicketNew.setWeightReal(weightReal);
        //附加材质
        fbaSpellTicketNew.setSurchargeMaterialMax(surchargeMaterialMax);
        //品名数
        fbaSpellTicketNew.setNumProName(gradeNum.size());
        //抛货系数
        fbaSpellTicketNew.setJettisonCoe(weightVol.subtract(weightReal));
        //平均箱重
        fbaSpellTicketNew.setAveBoxWeight(weightReal.divide(new BigDecimal(numBox), 2, RoundingMode.HALF_UP));


        //实际品名附加费 = 超出的品名*品名标准
        fbaSpellTicketNew.setPriceProNameExtraPredict(logsticsPattern.getPriceProNamePerOne().multiply(new BigDecimal(num>0?num:0)).setScale(2, BigDecimal.ROUND_HALF_UP));
        //设置实际材质附加费=材质计费*实际计重
        fbaSpellTicketNew.setPriceQualityExtraPredict(texture.multiply(fbaSpellTicketNew.getWeightCal()).setScale(2, BigDecimal.ROUND_HALF_UP));
        fbaSpellTicketNew.setPriceClearanceOpe(logsticsPattern.getPriceClearanceOpe());
        //梯度计重单价=(实际计重满足区间的值)
        BigDecimal finalWeightCalNew = fbaSpellTicketNew.getWeightCal();
        tdjzPrice = logisticsMmodeGrads.stream().filter(logisticsMmodeGrads1 -> finalWeightCalNew.compareTo(logisticsMmodeGrads1.getStartSection()) >= 0
                && finalWeightCalNew.compareTo(logisticsMmodeGrads1.getEndSection()) <= 0).collect(Collectors.toList());
        //计重单价=梯度计重单价+抛重计重单价
        weightPrice = (tdjzPrice.size()!=0?tdjzPrice.get(0).getKg():BigDecimal.ZERO);
        //实际计重费=(预估计重*计重单价)
        fbaSpellTicketNew.setPriceTranCalWeightPredict(finalWeightCalNew.multiply(weightPrice));
        //实际物流费用 = 实际计重运费+实际材质附加费+实际品名附加费+实际清关费
        fbaSpellTicketNew.setActualLogisticsFreight(fbaSpellTicketNew.getPriceTranCalWeightPredict().
                add(fbaSpellTicketNew.getPriceQualityExtraPredict()).add(fbaSpellTicketNew.getPriceProNameExtraPredict()
                .add(fbaSpellTicketNew.getPriceClearanceOpe())));

        FbaSpellTicket fbaSpellTicket;
        for (int i = 0; i < 3; i++) {
            fbaSpellTicket = new FbaSpellTicket();
            switch (i) {
                case 0:
                    fbaSpellTicket.setShipmentId("总计金额");
                    fbaSpellTicket.setActualLogisticsFreight(actualLogisticsFreightTolOld);
                    fbaSpellTicket.setPriceTranCalWeightPredict(priceTranCalWeightPredictTolOld);
                    fbaSpellTicket.setPriceQualityExtraPredict(priceQualityExtraPredictTolOld);
                    fbaSpellTicket.setPriceProNameExtraPredict(priceProNameExtraPredictTolOld);
                    fbaSpellTicket.setPriceClearanceOpe(priceClearanceOpeTolOld);
                    fbaSpellTicket.setWeightCal(weightCalTol);
                    fbaSpellTicket.setWeightReal(weightRealTol);
                    fbaSpellTicket.setWeightVol(weightVolTol);
                    fbaSpellTicket.setSurchargeMaterialMax(String.join(",", gradeNumNew));
                    fbaSpellTicket.setNumProName(pMNum);
                    fbaSpellTicket.setNumBox(numBox);
                    break;
                case 1:
                    fbaSpellTicket.setShipmentId("拼票金额");
                    fbaSpellTicket.setActualLogisticsFreight(fbaSpellTicketNew.getActualLogisticsFreight());
                    fbaSpellTicket.setPriceTranCalWeightPredict(fbaSpellTicketNew.getPriceTranCalWeightPredict());
                    fbaSpellTicket.setPriceQualityExtraPredict(fbaSpellTicketNew.getPriceQualityExtraPredict());
                    fbaSpellTicket.setPriceProNameExtraPredict(fbaSpellTicketNew.getPriceProNameExtraPredict());
                    fbaSpellTicket.setPriceClearanceOpe(fbaSpellTicketNew.getPriceClearanceOpe());
                    fbaSpellTicket.setWeightCal(fbaSpellTicketNew.getWeightCal());
                    fbaSpellTicket.setWeightReal(fbaSpellTicketNew.getWeightReal());
                    fbaSpellTicket.setWeightVol(fbaSpellTicketNew.getWeightVol());
                    fbaSpellTicket.setSurchargeMaterialMax(surchargeMaterialMax);
                    fbaSpellTicket.setNumProName(gradeNum.size());
                    fbaSpellTicket.setNumBox(numBox);
                    fbaSpellTicket.setJettisonCoe(fbaSpellTicketNew.getJettisonCoe());
                    fbaSpellTicket.setAveBoxWeight(fbaSpellTicketNew.getAveBoxWeight());
                    break;
                case 2:
                    fbaSpellTicket.setShipmentId("差额金额");
                    fbaSpellTicket.setActualLogisticsFreight(actualLogisticsFreightTolOld.subtract(fbaSpellTicketNew.getActualLogisticsFreight()));
                    fbaSpellTicket.setPriceTranCalWeightPredict(priceTranCalWeightPredictTolOld.subtract(fbaSpellTicketNew.getPriceTranCalWeightPredict()));
                    fbaSpellTicket.setPriceQualityExtraPredict(priceQualityExtraPredictTolOld.subtract(fbaSpellTicketNew.getPriceQualityExtraPredict()));
                    fbaSpellTicket.setPriceProNameExtraPredict(priceProNameExtraPredictTolOld.subtract(fbaSpellTicketNew.getPriceProNameExtraPredict()));
                    fbaSpellTicket.setPriceClearanceOpe(priceClearanceOpeTolOld.subtract(fbaSpellTicketNew.getPriceClearanceOpe()));
                    fbaSpellTicket.setWeightCal(weightCalTol.subtract(fbaSpellTicketNew.getWeightCal()));
                    fbaSpellTicket.setWeightReal(weightRealTol.subtract(fbaSpellTicketNew.getWeightReal()));
                    fbaSpellTicket.setWeightVol(weightVolTol.subtract(fbaSpellTicketNew.getWeightVol()));
                    fbaSpellTicket.setSurchargeMaterialMax("无");
                    fbaSpellTicket.setNumProName(pMNum - gradeNum.size());
                    fbaSpellTicket.setNumBox(0);
                    break;
            }
            fbaSpellTicketList.add(fbaSpellTicket);
        }
        return fbaSpellTicketList;
    }

    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult saveData(Map<String, Object> params) {
        //返回id用于前端查询
        String resGuid = "";
        String guidList = String.valueOf(params.get("guidList"));
        String[] guidListSplit = guidList.split(",");
        params.put("guidListSplit",guidListSplit);
        List<FbaSpellTicket> fbaSpellTicketList = fbaSpellTickMapper.select(params);
        if (fbaSpellTicketList.size() == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("拼票数据不存在,请核实后再操作!");
        }

        //根据主表的guid查询对应箱子所以信息
        List<FbaSpellTicketDetail> fbaSpellTicketDetail = fbaSpellTicketDetailMapper.findFbaSpellTicketDetail(params);

        Map<String, Object> params1 = new HashMap<String, Object>();
        params1.put("guid",params.get("guidLogsticsPattern"));
        //查询物流名称对应的数据
        LogsticsPattern logsticsPattern = logsticsPatternMapper.queryFirstByGuid(params1);
        params1.put("code",logsticsPattern.getCodeLogsticsServer());
        LogsticsServer logsticsserver = logsticsServerMapper.queryFirstByCode(params1);

        //获取物流名称详情
        Map<String, Object> params2 = new HashMap<String, Object>();
        params2.put("code",logsticsPattern.getCode());
        params2.put("logisticsMmodeGuid",logsticsPattern.getGuid());
        List<LogsticsPatternDetails> textureList = logsticsPatternDetailsMapper.findLogsticsPatternDetails(params2);
        //获取物流方式梯度
        List<LogisticsMmodeGrads> logisticsMmodeGradList = logsticsMmodeGradsMapper.findLogisticsMmodeGrads(params2);
        List<LogisticsMmodeGrads> logisticsMmodeGrads  = logisticsMmodeGradList.stream().filter(logisticsMmodeGrads1 ->
                "WLMC".equals(logisticsMmodeGrads1.getType())).collect(Collectors.toList());

        List<FbaSpellTicketDetail> fbaSpellTicketDetailNew;
        List<FbaSpellTicketDetail> fbaSpellTicketDetailOld;
        //抛重
        BigDecimal weightVol = BigDecimal.ZERO;
        BigDecimal weightVolNew;
        //最大的材质值
        BigDecimal texture = BigDecimal.ZERO;
        //品名数量
        Set<String> gradeNum = new HashSet<>();
        //品名材质
        Set<String> gradeNumNew = new HashSet<>();
        List<LogisticsMmodeGrads> tdjzPrice;
        //总箱重
        BigDecimal weightReal = BigDecimal.ZERO;
        //总计重
        BigDecimal weightCal = BigDecimal.ZERO;
        BigDecimal weightPrice;
        Integer num;
        ModuleNidAndBid moduleNidAndBid = null;
        Map<String, Object> params3;
        //重新计算每个fba箱子数据
        FbaLogsticsOrder fbaLogsticsOrder = null;
        List<FbaLogsticsOrder> fbaLogsticsOrderList = new ArrayList<>();
        List<FbaLogsticsOrderDetail> fbaLogsticsOrderDetailList = new ArrayList<>();
        List<FbaLogsticsOrderBox> fbaLogsticsOrderBoxList = new ArrayList<>();
//        List<FbaBox> fbaBoxList = new ArrayList<>();
//        FbaBox fbaBox;
        FbaLogsticsOrderBox fbaLogsticsOrderBox;
        FbaLogsticsOrderDetail fbaLogsticsOrderDetail;
        Integer numBox = 0;
        BigDecimal logisticsFeesXs = BigDecimal.ZERO;
        if (params.get("type").equals("1")){
            //添加物流订单数据
            params3 = new HashMap<String, Object>();
            params3.put("moduleTable", "TP_FbaLogsticsOrder");
            moduleNidAndBid = moduleNidAndBidMapper.findModuleNidAndBid(params3);    //有事务控制，制单异常不跳过单号
            fbaLogsticsOrder = new FbaLogsticsOrder();
            fbaLogsticsOrder.setGuid(RandomValueUtils.getGUID());
            fbaLogsticsOrder.setNid("0");
            fbaLogsticsOrder.setBid(moduleNidAndBid.getBid());
            fbaLogsticsOrder.setState("0");
            fbaLogsticsOrder.setStateName("无");
        }

        for (FbaSpellTicket fbaSpellTicket : fbaSpellTicketList) {
            if (fbaSpellTicket.getStateShareTicket().equals("4")) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("FBA编号:" + fbaSpellTicket.getShipmentId() + "数据已经生成物流订单,请核实后再操作!");
            }

            //修改拼票数据为已生成物流订单
            fbaSpellTicket.setSpellTicketState("1");
            numBox = numBox + fbaSpellTicket.getNumBox();
            logisticsFeesXs = logisticsFeesXs.add(fbaSpellTicket.getActualLogisticsFreight());


            fbaSpellTicketDetailNew = fbaSpellTicketDetail.stream().filter(fbaSpellTicketDeta -> fbaSpellTicketDeta.getFbaSpellTicketGuid().equals(fbaSpellTicket.getGuid())).collect(Collectors.toList());
            //实际的商品信息
            fbaSpellTicketDetailOld = JSON.parseArray(fbaSpellTicketDetailNew.get(0).getProductInfo(), FbaSpellTicketDetail.class);
            //计算材质最大值
            for (FbaSpellTicketDetail fbaSpellTicketDetail1 : fbaSpellTicketDetailOld) {
                String join = fbaSpellTicketDetail1.getNameGoodsCn() + '-' + fbaSpellTicketDetail1.getCodeGoodsHs() + '-' + fbaSpellTicketDetail1.getNameMaterialCn();
                gradeNum.add(join);
                gradeNumNew.add(fbaSpellTicketDetail1.getNameMaterialCn());

                //判断是否是混合材质
                if (fbaSpellTicketDetail1.getNameMaterialCn().indexOf(",") == -1) {
                    //赋值材质附加费(取最大值)
                    for (int j = 0; j < textureList.size(); j++) {
                        if (textureList.get(j).getMaterialName().equals(fbaSpellTicketDetail1.getNameMaterialCn())) {
                            if (textureList.get(j).getMaterialCost().compareTo(texture) > 0) {
                                texture = (textureList.get(j).getMaterialCost());
                            }
                        }
                    }
                } else {
                    String[] nameMaterialCnList = fbaSpellTicketDetail1.getNameMaterialCn().split(",");
                    for (String nameMaterialCn : nameMaterialCnList) {
                        for (int j = 0; j < textureList.size(); j++) {
                            if (textureList.get(j).getMaterialName().equals(nameMaterialCn)) {
                                if (textureList.get(j).getMaterialCost().compareTo(texture) > 0) {
                                    texture = (textureList.get(j).getMaterialCost());
                                }
                            }
                        }
                    }
                }
            }


            //新增拼票信息
            fbaLogsticsOrderDetail = new FbaLogsticsOrderDetail();
            BeanUtils.copyProperties(fbaSpellTicket,fbaLogsticsOrderDetail);
            fbaLogsticsOrderDetail.setGuid(RandomValueUtils.getGUID());
            fbaLogsticsOrderDetail.setCodeFbaLogsticsOrder(moduleNidAndBid.getBid());
            fbaLogsticsOrderDetail.setStateTrack("1");
            fbaLogsticsOrderDetail.setStateTrackName("已交付物流部");
            fbaLogsticsOrderDetail.setNameLogsticsPattern(logsticsPattern.getName());
            fbaLogsticsOrderDetail.setCodeLogsticsPattern(logsticsPattern.getCode());
            fbaLogsticsOrderDetailList.add(fbaLogsticsOrderDetail);

            //计算商品实重和抛重
            for (FbaSpellTicketDetail fbaSpellTicketDetail1 : fbaSpellTicketDetailNew) {
                weightVolNew = (new BigDecimal(fbaSpellTicketDetail1.getWidth()).multiply(new BigDecimal(fbaSpellTicketDetail1.getLength())
                        .multiply(new BigDecimal(fbaSpellTicketDetail1.getHeight())))).divide(new BigDecimal(logsticsPattern.getCoefficientWeight()), 2, RoundingMode.HALF_UP);
                fbaSpellTicketDetail1.setWeightVol(weightVolNew.toString());
                weightReal = weightReal.add((new BigDecimal(fbaSpellTicketDetail1.getWeight()).max(logsticsPattern.getWeightCalBySingle())));
                //实际计重=MAX(单箱实重，单箱起重)之和
                weightCal = weightCal.add((new BigDecimal(fbaSpellTicketDetail1.getWeight()).max(logsticsPattern.getWeightCalBySingle())));
                weightVol = weightVol.add(weightVolNew);


                //添加订单箱子数据
                fbaLogsticsOrderBox = new FbaLogsticsOrderBox();
                BeanUtils.copyProperties(fbaSpellTicketDetail1,fbaLogsticsOrderBox);
                fbaLogsticsOrderBox.setGuid(RandomValueUtils.getGUID());
                fbaLogsticsOrderBox.setCodeFbaLogsticsOrder(moduleNidAndBid.getBid());
                fbaLogsticsOrderBox.setLogsticsOrderDetailGuid(fbaLogsticsOrderDetail.getGuid());
                fbaLogsticsOrderBoxList.add(fbaLogsticsOrderBox);
            }


        }
        if (params.get("type").equals("1")){
            //赋值物流订单数据
            fbaLogsticsOrder.setNumBox(numBox);
            fbaLogsticsOrder.setLogisticsFeesXs(logisticsFeesXs);
            fbaLogsticsOrder.setCode(moduleNidAndBid.getBid());
            fbaLogsticsOrder.setCodeLogsticsPattern(logsticsPattern.getCode());
            fbaLogsticsOrder.setbUser(ShiroUtils.getUserId());
            fbaLogsticsOrder.setbDept(ShiroUtils.getMandatorDeptPath());
            fbaLogsticsOrder.setCreateUser(ShiroUtils.getMandatorName());
            fbaLogsticsOrder.setCreateTime(new Date());
            fbaLogsticsOrder.setAuditUser(null);
            fbaLogsticsOrder.setAuditTime(null);
            fbaLogsticsOrder.setStateTrack("1");
            fbaLogsticsOrder.setStateTrackName("已交付物流部");
            fbaLogsticsOrder.setDestinationFulfillmentCenterId(fbaSpellTicketList.get(0).getDestinationFulfillmentCenterId());
            fbaLogsticsOrder.setNameLogsticsWay(logsticsPattern.getName());
            fbaLogsticsOrder.setCodeLogsticsServer(logsticsserver.getName());
            fbaLogsticsOrder.setNameLogsticsPattern(logsticsPattern.getName());
            fbaLogsticsOrder.setCodeCompany(logsticsPattern.getCodeCompany());
            fbaLogsticsOrder.setNameCompany(logsticsPattern.getNameCompany());

            //超出品名=实际品名-实际免费品名数
            num = gradeNum.size()-logsticsPattern.getNumFreeProName();
            //实际计重 =  max(A1，抛重之和)进行约分
            fbaLogsticsOrder.setWeightCal(precision(weightCal.max(weightVol)));
            fbaLogsticsOrder.setWeightReal(weightReal);
            fbaLogsticsOrder.setWeightVol(weightVol);
            //品名免费数
            fbaLogsticsOrder.setNumFreeProName(String.valueOf(logsticsPattern.getNumFreeProName()));
            //品名实际数
            fbaLogsticsOrder.setNumProName(gradeNum.size());
            //品名附加费单价
            fbaLogsticsOrder.setNameSurchargePrice(logsticsPattern.getPriceProNamePerOne());
            //实际品名附加费 = 超出的品名*品名标准
            fbaLogsticsOrder.setPriceProNameExtraPredict(logsticsPattern.getPriceProNamePerOne().multiply(new BigDecimal(num>0?num:0)).setScale(2, BigDecimal.ROUND_HALF_UP));
            //设置实际材质附加费=材质计费*实际计重
            fbaLogsticsOrder.setPriceQualityExtraPredict(texture.multiply(fbaLogsticsOrder.getWeightCal()).setScale(2, BigDecimal.ROUND_HALF_UP));
            fbaLogsticsOrder.setPriceQualityExtra(texture);
            fbaLogsticsOrder.setPriceClearanceOpe(logsticsPattern.getPriceClearanceOpe());
            //梯度计重单价=(实际计重满足区间的值)
            BigDecimal finalWeightCalNew = fbaLogsticsOrder.getWeightCal();
            tdjzPrice = logisticsMmodeGrads.stream().filter(logisticsMmodeGrads1 -> finalWeightCalNew.compareTo(logisticsMmodeGrads1.getStartSection()) >= 0
                    && finalWeightCalNew.compareTo(logisticsMmodeGrads1.getEndSection()) <= 0).collect(Collectors.toList());
            //计重单价=梯度计重单价+抛重计重单价
            weightPrice = (tdjzPrice.size()!=0?tdjzPrice.get(0).getKg():BigDecimal.ZERO);
            fbaLogsticsOrder.setJzPrice(weightPrice);
            fbaLogsticsOrder.setSurchargeMaterialMax(String.join(",", gradeNumNew));

            //实际计重费=(预估计重*计重单价)
            fbaLogsticsOrder.setPriceTranCalWeightPredict(finalWeightCalNew.multiply(weightPrice));
            //实际物流费用 = 实际计重运费+实际材质附加费+实际品名附加费+实际清关费
            fbaLogsticsOrder.setActualLogisticsFreight(fbaLogsticsOrder.getPriceTranCalWeightPredict().
                    add(fbaLogsticsOrder.getPriceQualityExtraPredict()).add(fbaLogsticsOrder.getPriceProNameExtraPredict()
                    .add(fbaLogsticsOrder.getPriceClearanceOpe())));
            fbaLogsticsOrder.setFbaSpellTicketGuid(fbaSpellTicketList.stream().map(FbaSpellTicket::getGuid).collect(Collectors.joining(",")));
            fbaLogsticsOrderList.add(fbaLogsticsOrder);
        }

        // 批量新赠物流订单
        fbaLogsticsOrderMapper.batchInsert(fbaLogsticsOrderList);
        // 批量新赠物流订单详情
        fbaLogsticsOrderDetailMapper.batchInsert(fbaLogsticsOrderDetailList);
        // 批量新赠物流订单箱子数据
        fbaLogsticsOrderBoxMapper.batchInsert(fbaLogsticsOrderBoxList);
        // 批量修改物流拼票的数据
        fbaSpellTickMapper.batchUpdate(fbaSpellTicketList);
        // 批量修改头程装箱数据的发货状态
//        fbaBoxMapper.updateBatchCode(fbaBoxList);
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"),resGuid);
    }

    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult noTicket(Map<String, Object> params) {
        //返回id用于前端查询
        String resGuid = "";
        String guidList = String.valueOf(params.get("guidList"));
        String[] guidListSplit = guidList.split(",");
        params.put("guidListSplit",guidListSplit);
        List<FbaSpellTicket> fbaSpellTicketList = fbaSpellTickMapper.select(params);
        if (fbaSpellTicketList.size() == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("拼票数据不存在,请核实后再操作!");
        }

        //根据主表的guid查询对应箱子所以信息
        List<FbaSpellTicketDetail> fbaSpellTicketDetail = fbaSpellTicketDetailMapper.findFbaSpellTicketDetail(params);

        Map<String, Object> params1 = new HashMap<String, Object>();
        params1.put("guid",params.get("guidLogsticsPattern"));
        //查询物流名称对应的数据
        LogsticsPattern logsticsPattern = logsticsPatternMapper.queryFirstByGuid(params1);
        params1.put("code",logsticsPattern.getCodeLogsticsServer());
        LogsticsServer logsticsserver = logsticsServerMapper.queryFirstByCode(params1);

        //获取物流名称详情
        Map<String, Object> params2 = new HashMap<String, Object>();
        params2.put("code",logsticsPattern.getCode());
        params2.put("logisticsMmodeGuid",logsticsPattern.getGuid());
        List<LogsticsPatternDetails> textureList = logsticsPatternDetailsMapper.findLogsticsPatternDetails(params2);
        //获取物流方式梯度
        List<LogisticsMmodeGrads> logisticsMmodeGradList = logsticsMmodeGradsMapper.findLogisticsMmodeGrads(params2);
        List<LogisticsMmodeGrads> logisticsMmodeGrads  = logisticsMmodeGradList.stream().filter(logisticsMmodeGrads1 ->
                "WLMC".equals(logisticsMmodeGrads1.getType())).collect(Collectors.toList());

        List<FbaSpellTicketDetail> fbaSpellTicketDetailNew;
        List<FbaSpellTicketDetail> fbaSpellTicketDetailOld;
        //抛重
        BigDecimal weightVol = BigDecimal.ZERO;
        BigDecimal weightVolNew;
        //最大的材质值
        BigDecimal texture;
        //品名数量
        Set<String> gradeNum;
        //品名材质
        Set<String> gradeNumNew;
        List<LogisticsMmodeGrads> tdjzPrice;
        //总箱重
        BigDecimal weightReal = BigDecimal.ZERO;
        BigDecimal weightCal = BigDecimal.ZERO;
        BigDecimal weightPrice;
        Integer num;
        ModuleNidAndBid moduleNidAndBid = null;
        Map<String, Object> params3;
        //重新计算每个fba箱子数据
        FbaLogsticsOrder fbaLogsticsOrder = null;
        List<FbaLogsticsOrder> fbaLogsticsOrderList = new ArrayList<>();
        List<FbaLogsticsOrderDetail> fbaLogsticsOrderDetailList = new ArrayList<>();
        List<FbaLogsticsOrderBox> fbaLogsticsOrderBoxList = new ArrayList<>();
//        List<FbaBox> fbaBoxList = new ArrayList<>();
//        FbaBox fbaBox;
        FbaLogsticsOrderBox fbaLogsticsOrderBox;
        FbaLogsticsOrderDetail fbaLogsticsOrderDetail;
        for (FbaSpellTicket fbaSpellTicket : fbaSpellTicketList) {
            if (fbaSpellTicket.getStateShareTicket().equals("4")) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("FBA编号:" + fbaSpellTicket.getShipmentId() + "数据已经生成物流订单,请核实后再操作!");
            }

            //添加物流订单数据
            params3 = new HashMap<String, Object>();
            params3.put("moduleTable", "TP_FbaLogsticsOrder");
            moduleNidAndBid = moduleNidAndBidMapper.findModuleNidAndBid(params3);    //有事务控制，制单异常不跳过单号
            fbaLogsticsOrder = new FbaLogsticsOrder();
            fbaLogsticsOrder.setGuid(RandomValueUtils.getGUID());
            fbaLogsticsOrder.setNid("0");
            fbaLogsticsOrder.setBid(moduleNidAndBid.getBid());
            fbaLogsticsOrder.setState("0");
            fbaLogsticsOrder.setStateName("无");
            fbaLogsticsOrder.setNumBox(fbaSpellTicket.getNumBox());
            fbaLogsticsOrder.setLogisticsFeesXs(fbaSpellTicket.getActualLogisticsFreight());

            //修改拼票数据为已生成物流订单
            fbaSpellTicket.setSpellTicketState("1");

            fbaSpellTicketDetailNew = fbaSpellTicketDetail.stream().filter(fbaSpellTicketDeta -> fbaSpellTicketDeta.getFbaSpellTicketGuid().equals(fbaSpellTicket.getGuid())).collect(Collectors.toList());
            //实际的商品信息
            fbaSpellTicketDetailOld = JSON.parseArray(fbaSpellTicketDetailNew.get(0).getProductInfo(), FbaSpellTicketDetail.class);

            gradeNum = new HashSet<>();
            gradeNumNew = new HashSet<>();
            texture = BigDecimal.ZERO;
            //计算材质最大值
            for (FbaSpellTicketDetail fbaSpellTicketDetail1 : fbaSpellTicketDetailOld) {
                String join = fbaSpellTicketDetail1.getNameGoodsCn() + '-' + fbaSpellTicketDetail1.getCodeGoodsHs() + '-' + fbaSpellTicketDetail1.getNameMaterialCn();
                gradeNum.add(join);
                gradeNumNew.add(fbaSpellTicketDetail1.getNameGoodsCn());

                //判断是否是混合材质
                if (fbaSpellTicketDetail1.getNameMaterialCn().indexOf(",") == -1) {
                    //赋值材质附加费(取最大值)
                    for (int j = 0; j < textureList.size(); j++) {
                        if (textureList.get(j).getMaterialName().equals(fbaSpellTicketDetail1.getNameMaterialCn())) {
                            if (textureList.get(j).getMaterialCost().compareTo(texture) > 0) {
                                texture = (textureList.get(j).getMaterialCost());
                            }
                        }
                    }
                } else {
                    String[] nameMaterialCnList = fbaSpellTicketDetail1.getNameMaterialCn().split(",");
                    for (String nameMaterialCn : nameMaterialCnList) {
                        for (int j = 0; j < textureList.size(); j++) {
                            if (textureList.get(j).getMaterialName().equals(nameMaterialCn)) {
                                if (textureList.get(j).getMaterialCost().compareTo(texture) > 0) {
                                    texture = (textureList.get(j).getMaterialCost());
                                }
                            }
                        }
                    }
                }
            }

            //新增拼票信息
            fbaLogsticsOrderDetail = new FbaLogsticsOrderDetail();
            BeanUtils.copyProperties(fbaSpellTicket,fbaLogsticsOrderDetail);
            fbaLogsticsOrderDetail.setGuid(RandomValueUtils.getGUID());
            fbaLogsticsOrderDetail.setCodeFbaLogsticsOrder(moduleNidAndBid.getBid());
            fbaLogsticsOrderDetail.setNameLogsticsPattern(logsticsPattern.getName());
            fbaLogsticsOrderDetail.setCodeLogsticsPattern(logsticsPattern.getCode());
            fbaLogsticsOrderDetailList.add(fbaLogsticsOrderDetail);

            //计算商品实重和抛重
            for (FbaSpellTicketDetail fbaSpellTicketDetail1 : fbaSpellTicketDetailNew) {
                weightVolNew = (new BigDecimal(fbaSpellTicketDetail1.getWidth()).multiply(new BigDecimal(fbaSpellTicketDetail1.getLength())
                        .multiply(new BigDecimal(fbaSpellTicketDetail1.getHeight())))).divide(new BigDecimal(logsticsPattern.getCoefficientWeight()), 2, RoundingMode.HALF_UP);
                fbaSpellTicketDetail1.setWeightVol(weightVolNew.toString());
                weightReal = weightReal.add(new BigDecimal(fbaSpellTicketDetail1.getWeight()));
                //实际计重=MAX(单箱实重，单箱起重)之和
                weightCal = weightCal.add((new BigDecimal(fbaSpellTicketDetail1.getWeight()).max(logsticsPattern.getWeightCalBySingle())));
                weightVol = weightVol.add(weightVolNew);

                //添加订单箱子数据
                fbaLogsticsOrderBox = new FbaLogsticsOrderBox();
                BeanUtils.copyProperties(fbaSpellTicketDetail1,fbaLogsticsOrderBox);
                fbaLogsticsOrderBox.setGuid(RandomValueUtils.getGUID());
                fbaLogsticsOrderBox.setCodeFbaLogsticsOrder(moduleNidAndBid.getBid());
                fbaLogsticsOrderBox.setLogsticsOrderDetailGuid(fbaLogsticsOrderDetail.getGuid());
                fbaLogsticsOrderBoxList.add(fbaLogsticsOrderBox);
            }


            //赋值物流订单数据
            fbaLogsticsOrder.setCode(moduleNidAndBid.getBid());
            fbaLogsticsOrder.setCodeLogsticsPattern(logsticsPattern.getCode());
            fbaLogsticsOrder.setbUser(ShiroUtils.getUserId());
            fbaLogsticsOrder.setbDept(ShiroUtils.getMandatorDeptPath());
            fbaLogsticsOrder.setCreateUser(ShiroUtils.getMandatorName());
            fbaLogsticsOrder.setCreateTime(new Date());
            fbaLogsticsOrder.setAuditUser(null);
            fbaLogsticsOrder.setAuditTime(null);
            fbaLogsticsOrder.setStateTrack(fbaSpellTicket.getStateTrack());
            fbaLogsticsOrder.setStateTrackName(fbaSpellTicket.getStateTrackName());
            fbaLogsticsOrder.setDestinationFulfillmentCenterId(fbaSpellTicketList.get(0).getDestinationFulfillmentCenterId());
            fbaLogsticsOrder.setNameLogsticsWay(logsticsPattern.getNameLogsticsWay());
            fbaLogsticsOrder.setCodeLogsticsServer(logsticsserver.getName());
            fbaLogsticsOrder.setNameLogsticsPattern(logsticsPattern.getName());
            fbaLogsticsOrder.setCodeCompany(logsticsPattern.getCodeCompany());
            fbaLogsticsOrder.setNameCompany(logsticsPattern.getNameCompany());

            //超出品名=实际品名-实际免费品名数
            num = gradeNum.size()-logsticsPattern.getNumFreeProName();
            //实际计重 =  max(A1，抛重之和)进行约分
            fbaLogsticsOrder.setWeightCal(precision(weightCal.max(weightVol)));
            fbaLogsticsOrder.setWeightReal(weightReal);
            fbaLogsticsOrder.setWeightVol(weightVol);
            //品名免费数
            fbaLogsticsOrder.setNumFreeProName(String.valueOf(logsticsPattern.getNumFreeProName()));
            //品名实际数
            fbaLogsticsOrder.setNumProName(gradeNum.size());
            //品名附加费单价
            fbaLogsticsOrder.setNameSurchargePrice(logsticsPattern.getPriceProNamePerOne());
            //实际品名附加费 = 超出的品名*品名标准
            fbaLogsticsOrder.setPriceProNameExtraPredict(logsticsPattern.getPriceProNamePerOne().multiply(new BigDecimal(num>0?num:0)).setScale(2, BigDecimal.ROUND_HALF_UP));
            //设置实际材质附加费=材质计费*实际计重
            fbaLogsticsOrder.setPriceQualityExtraPredict(texture.multiply(fbaLogsticsOrder.getWeightCal()).setScale(2, BigDecimal.ROUND_HALF_UP));
            fbaLogsticsOrder.setPriceQualityExtra(texture);
            fbaLogsticsOrder.setPriceClearanceOpe(logsticsPattern.getPriceClearanceOpe());
            //梯度计重单价=(实际计重满足区间的值)
            BigDecimal finalWeightCalNew = fbaLogsticsOrder.getWeightCal();
            tdjzPrice = logisticsMmodeGrads.stream().filter(logisticsMmodeGrads1 -> finalWeightCalNew.compareTo(logisticsMmodeGrads1.getStartSection()) >= 0
                    && finalWeightCalNew.compareTo(logisticsMmodeGrads1.getEndSection()) <= 0).collect(Collectors.toList());
            //计重单价=梯度计重单价+抛重计重单价
            weightPrice = (tdjzPrice.size()!=0?tdjzPrice.get(0).getKg():BigDecimal.ZERO);
            fbaLogsticsOrder.setJzPrice(weightPrice);
            fbaLogsticsOrder.setSurchargeMaterialMax(String.join(",", gradeNumNew));

            //实际计重费=(预估计重*计重单价)
            fbaLogsticsOrder.setPriceTranCalWeightPredict(finalWeightCalNew.multiply(weightPrice));
            //实际物流费用 = 实际计重运费+实际材质附加费+实际品名附加费+实际清关费
            fbaLogsticsOrder.setActualLogisticsFreight(fbaLogsticsOrder.getPriceTranCalWeightPredict().
                    add(fbaLogsticsOrder.getPriceQualityExtraPredict()).add(fbaLogsticsOrder.getPriceProNameExtraPredict()
                    .add(fbaLogsticsOrder.getPriceClearanceOpe())));
            fbaLogsticsOrder.setFbaSpellTicketGuid(fbaSpellTicketList.stream().map(FbaSpellTicket::getGuid).collect(Collectors.joining(",")));
            // 批量新赠物流订单
            fbaLogsticsOrderMapper.insertFbaLogsticsOrder(fbaLogsticsOrder);
        }

        // 批量新赠物流订单详情
        fbaLogsticsOrderDetailMapper.batchInsert(fbaLogsticsOrderDetailList);
        // 批量新赠物流订单箱子数据
        fbaLogsticsOrderBoxMapper.batchInsert(fbaLogsticsOrderBoxList);
        // 批量修改物流拼票的数据
        fbaSpellTickMapper.batchUpdate(fbaSpellTicketList);
//        // 批量修改头程装箱数据的发货状态
//        fbaBoxMapper.updateBatchCode(fbaBoxList);
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"),resGuid);
    }

    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult loadDelivery(Map<String, Object> params) {

        //返回id用于前端查询
        String resGuid = "";
        String guidList = String.valueOf(params.get("guidList"));
        String[] guidListSplit = guidList.split(",");
        params.put("guidListSplit",guidListSplit);
        List<FbaSpellTicket> fbaSpellTicketList = fbaSpellTickMapper.select(params);
        if (fbaSpellTicketList.size() == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("拼票数据不存在,请核实后再操作!");
        }

        //根据主表的guid查询对应箱子所以信息
        List<FbaSpellTicketDetail> fbaSpellTicketDetail = fbaSpellTicketDetailMapper.findFbaSpellTicketDetail(params);

        Map<String, Object> params1 = new HashMap<String, Object>();
        params1.put("guid",params.get("guidLogsticsPattern"));
        //查询物流名称对应的数据
        LogsticsPattern logsticsPattern = logsticsPatternMapper.queryFirstByGuid(params1);
        params1.put("code",logsticsPattern.getCodeLogsticsServer());
        LogsticsServer logsticsserver = logsticsServerMapper.queryFirstByCode(params1);

        //获取物流名称详情
        Map<String, Object> params2 = new HashMap<String, Object>();
        params2.put("code",logsticsPattern.getCode());
        params2.put("logisticsMmodeGuid",logsticsPattern.getGuid());
        List<LogsticsPatternDetails> textureList = logsticsPatternDetailsMapper.findLogsticsPatternDetails(params2);
        //获取物流方式梯度
        List<LogisticsMmodeGrads> logisticsMmodeGradList = logsticsMmodeGradsMapper.findLogisticsMmodeGrads(params2);
        List<LogisticsMmodeGrads> logisticsMmodeGrads  = logisticsMmodeGradList.stream().filter(logisticsMmodeGrads1 ->
                "WLMC".equals(logisticsMmodeGrads1.getType())).collect(Collectors.toList());

        List<FbaSpellTicketDetail> fbaSpellTicketDetailNew;
        List<FbaSpellTicketDetail> fbaSpellTicketDetailOld;
        //抛重
        BigDecimal weightVol = BigDecimal.ZERO;
        BigDecimal weightVolNew;
        //最大的材质值
        BigDecimal texture;
        //品名数量
        Set<String> gradeNum;
        //品名材质
        Set<String> gradeNumNew;
        List<LogisticsMmodeGrads> tdjzPrice;
        //总箱重
        BigDecimal weightReal = BigDecimal.ZERO;
        BigDecimal weightCal = BigDecimal.ZERO;
        BigDecimal weightPrice;
        Integer num;
        ModuleNidAndBid moduleNidAndBid = null;
        Map<String, Object> params3;
        //重新计算每个fba箱子数据
        FbaLogsticsOrder fbaLogsticsOrder = null;
        List<FbaLogsticsOrder> fbaLogsticsOrderList = new ArrayList<>();
        List<FbaLogsticsOrderDetail> fbaLogsticsOrderDetailList = new ArrayList<>();
        List<FbaLogsticsOrderBox> fbaLogsticsOrderBoxList = new ArrayList<>();
        SysAccountBandDept sysAccountBandDept;
        AccountCountForCompany logisticsAccount;
        AccountCountForCompany operationAccount;
        AccountDetailedForCompany account;
        AccountDetailedForCompany account1;
        List<AccountDetailedForCompany> accountList =new ArrayList<>();
        FbaLogsticsOrderBox fbaLogsticsOrderBox;
        FbaLogsticsOrderDetail fbaLogsticsOrderDetail;
        for (FbaSpellTicket fbaSpellTicket : fbaSpellTicketList) {
            if (fbaSpellTicket.getStateShareTicket().equals("4")) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("FBA编号:" + fbaSpellTicket.getShipmentId() + "数据已经生成物流订单,请核实后再操作!");
            }

            //添加物流订单数据
            params3 = new HashMap<String, Object>();
            params3.put("moduleTable", "TP_FbaLogsticsOrder");
            moduleNidAndBid = moduleNidAndBidMapper.findModuleNidAndBid(params3);    //有事务控制，制单异常不跳过单号
            fbaLogsticsOrder = new FbaLogsticsOrder();
            fbaLogsticsOrder.setGuid(RandomValueUtils.getGUID());
            fbaLogsticsOrder.setNid("0");
            fbaLogsticsOrder.setBid(moduleNidAndBid.getBid());
            fbaLogsticsOrder.setState("0");
            fbaLogsticsOrder.setStateName("无");
            fbaLogsticsOrder.setNumBox(fbaSpellTicket.getNumBox());
            //抛发金额
            fbaLogsticsOrder.setLogisticsFeesXs(fbaSpellTicket.getActualLogisticsFreightPf());

            //修改拼票数据为已生成物流订单
            fbaSpellTicket.setSpellTicketState("1");

            fbaSpellTicketDetailNew = fbaSpellTicketDetail.stream().filter(fbaSpellTicketDeta -> fbaSpellTicketDeta.getFbaSpellTicketGuid().equals(fbaSpellTicket.getGuid())).collect(Collectors.toList());
            //实际的商品信息
            fbaSpellTicketDetailOld = JSON.parseArray(fbaSpellTicketDetailNew.get(0).getProductInfo(), FbaSpellTicketDetail.class);

            gradeNum = new HashSet<>();
            gradeNumNew = new HashSet<>();
            texture = BigDecimal.ZERO;
            //计算材质最大值
            for (FbaSpellTicketDetail fbaSpellTicketDetail1 : fbaSpellTicketDetailOld) {
                String join = fbaSpellTicketDetail1.getNameGoodsCn() + '-' + fbaSpellTicketDetail1.getCodeGoodsHs() + '-' + fbaSpellTicketDetail1.getNameMaterialCn();
                gradeNum.add(join);
                gradeNumNew.add(fbaSpellTicketDetail1.getNameGoodsCn());

                //判断是否是混合材质
                if (fbaSpellTicketDetail1.getNameMaterialCn().indexOf(",") == -1) {
                    //赋值材质附加费(取最大值)
                    for (int j = 0; j < textureList.size(); j++) {
                        if (textureList.get(j).getMaterialName().equals(fbaSpellTicketDetail1.getNameMaterialCn())) {
                            if (textureList.get(j).getMaterialCost().compareTo(texture) > 0) {
                                texture = (textureList.get(j).getMaterialCost());
                            }
                        }
                    }
                } else {
                    String[] nameMaterialCnList = fbaSpellTicketDetail1.getNameMaterialCn().split(",");
                    for (String nameMaterialCn : nameMaterialCnList) {
                        for (int j = 0; j < textureList.size(); j++) {
                            if (textureList.get(j).getMaterialName().equals(nameMaterialCn)) {
                                if (textureList.get(j).getMaterialCost().compareTo(texture) > 0) {
                                    texture = (textureList.get(j).getMaterialCost());
                                }
                            }
                        }
                    }
                }
            }

            //新增拼票信息
            fbaLogsticsOrderDetail = new FbaLogsticsOrderDetail();
            BeanUtils.copyProperties(fbaSpellTicket,fbaLogsticsOrderDetail);
            fbaLogsticsOrderDetail.setGuid(RandomValueUtils.getGUID());
            fbaLogsticsOrderDetail.setCodeFbaLogsticsOrder(moduleNidAndBid.getBid());
            fbaLogsticsOrderDetail.setNameLogsticsPattern(logsticsPattern.getName());
            fbaLogsticsOrderDetail.setCodeLogsticsPattern(logsticsPattern.getCode());
            fbaLogsticsOrderDetailList.add(fbaLogsticsOrderDetail);

            //计算商品实重和抛重
            for (FbaSpellTicketDetail fbaSpellTicketDetail1 : fbaSpellTicketDetailNew) {
                weightVolNew = (new BigDecimal(fbaSpellTicketDetail1.getWidth()).multiply(new BigDecimal(fbaSpellTicketDetail1.getLength())
                        .multiply(new BigDecimal(fbaSpellTicketDetail1.getHeight())))).divide(new BigDecimal(logsticsPattern.getCoefficientWeight()), 2, RoundingMode.HALF_UP);
                fbaSpellTicketDetail1.setWeightVol(weightVolNew.toString());
                weightReal = weightReal.add(new BigDecimal(fbaSpellTicketDetail1.getWeight()));
                //实际计重=MAX(单箱实重，单箱起重)之和
                weightCal = weightCal.add((new BigDecimal(fbaSpellTicketDetail1.getWeight()).max(logsticsPattern.getWeightCalBySingle())));
                weightVol = weightVol.add(weightVolNew);

                //添加订单箱子数据
                fbaLogsticsOrderBox = new FbaLogsticsOrderBox();
                BeanUtils.copyProperties(fbaSpellTicketDetail1,fbaLogsticsOrderBox);
                fbaLogsticsOrderBox.setGuid(RandomValueUtils.getGUID());
                fbaLogsticsOrderBox.setCodeFbaLogsticsOrder(moduleNidAndBid.getBid());
                fbaLogsticsOrderBox.setLogsticsOrderDetailGuid(fbaLogsticsOrderDetail.getGuid());
                fbaLogsticsOrderBoxList.add(fbaLogsticsOrderBox);
            }


            //赋值物流订单数据
            fbaLogsticsOrder.setCode(moduleNidAndBid.getBid());
            fbaLogsticsOrder.setCodeLogsticsPattern(logsticsPattern.getCode());
            fbaLogsticsOrder.setbUser(ShiroUtils.getUserId());
            fbaLogsticsOrder.setbDept(ShiroUtils.getMandatorDeptPath());
            fbaLogsticsOrder.setCreateUser(ShiroUtils.getMandatorName());
            fbaLogsticsOrder.setCreateTime(new Date());
            fbaLogsticsOrder.setAuditUser(null);
            fbaLogsticsOrder.setAuditTime(null);
            fbaLogsticsOrder.setStateTrack(fbaSpellTicket.getStateTrack());
            fbaLogsticsOrder.setStateTrackName(fbaSpellTicket.getStateTrackName());
            fbaLogsticsOrder.setDestinationFulfillmentCenterId(fbaSpellTicketList.get(0).getDestinationFulfillmentCenterId());
            fbaLogsticsOrder.setNameLogsticsWay(logsticsPattern.getNameLogsticsWay());
            fbaLogsticsOrder.setCodeLogsticsServer(logsticsserver.getName());
            fbaLogsticsOrder.setNameLogsticsPattern(logsticsPattern.getName());
            fbaLogsticsOrder.setCodeCompany(logsticsPattern.getCodeCompany());
            fbaLogsticsOrder.setNameCompany(logsticsPattern.getNameCompany());

            //实际抛发清关费=清关费单价
            fbaLogsticsOrder.setPriceClearanceOpe(logsticsPattern.getPriceClearanceOpe());
            //超出品名=实际品名-实际免费品名数(抛发实际品名免费数=品名免费数)
            num = gradeNum.size() - logsticsPattern.getNumFreeProName();
            //品名免费数
            fbaLogsticsOrder.setNumFreeProName(String.valueOf(logsticsPattern.getNumFreeProName()));
            //品名实际数
            fbaLogsticsOrder.setNumProName(gradeNum.size());
            //品名附加费单价
            fbaLogsticsOrder.setNameSurchargePrice(logsticsPattern.getPriceProNamePerOne());
            //实际品名附加费 = 超出的品名*品名标准
            fbaLogsticsOrder.setPriceProNameExtraPredict(logsticsPattern.getPriceProNamePerOne().multiply(new BigDecimal(num > 0 ? num : 0)).setScale(2, BigDecimal.ROUND_HALF_UP));

            //抛发计重：【=MAX（装箱抛重，单票起重）约分】
            BigDecimal weightCalPf = precision(logsticsPattern.getSinglePassCrane().max(weightVol));
            //实际抛发材质附加费、费用说明：实际抛发材质附加费=MAX（装箱抛重，单票起重）*材质附加单价
            fbaLogsticsOrder.setPriceQualityExtra(texture);
            fbaLogsticsOrder.setPriceQualityExtraPredict(texture.multiply(weightCalPf).setScale(2, BigDecimal.ROUND_HALF_UP));

            //实际计重 =  抛发计重
            fbaLogsticsOrder.setWeightCal(weightCalPf);
            fbaLogsticsOrder.setWeightReal(weightReal);
            fbaLogsticsOrder.setWeightVol(weightVol);

            //梯度计重单价=(实际计重满足区间的值)
            tdjzPrice = logisticsMmodeGrads.stream().filter(logisticsMmodeGrads1 -> weightCalPf.compareTo(logisticsMmodeGrads1.getStartSection()) >= 0
                    && weightCalPf.compareTo(logisticsMmodeGrads1.getEndSection()) <= 0).collect(Collectors.toList());
            //计重单价=梯度计重单价+抛重计重单价
            weightPrice = (tdjzPrice.size() != 0 ? tdjzPrice.get(0).getKg() : BigDecimal.ZERO);
            fbaLogsticsOrder.setJzPrice(weightPrice);
            fbaLogsticsOrder.setSurchargeMaterialMax(String.join(",", gradeNumNew));

            //实际抛发计重运费、费用说明：实际抛发计重运费=MAX（装箱抛重，单票起重）*抛发计重单价
            fbaLogsticsOrder.setPriceTranCalWeightPredict((weightCalPf.multiply(weightPrice)).setScale(2, BigDecimal.ROUND_HALF_UP));
            //实际物流费用 = 实际计重运费+实际材质附加费+实际品名附加费+实际清关费
            fbaLogsticsOrder.setActualLogisticsFreight(fbaLogsticsOrder.getPriceTranCalWeightPredict().
                    add(fbaLogsticsOrder.getPriceQualityExtraPredict()).add(fbaLogsticsOrder.getPriceProNameExtraPredict()
                    .add(fbaLogsticsOrder.getPriceClearanceOpe())));
            fbaLogsticsOrder.setFbaSpellTicketGuid(fbaSpellTicketList.stream().map(FbaSpellTicket::getGuid).collect(Collectors.joining(",")));
            // 批量新赠物流订单
            fbaLogsticsOrderMapper.insertFbaLogsticsOrder(fbaLogsticsOrder);

            // 查询物流部账号
            sysAccountBandDept = sysAccountBandDeptMapper.findByAccountId("WLB");
            if (sysAccountBandDept == null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("物流部门绑定账户未启用或不存在,请核实后再操作!");
            }
            // 物流公司
            logisticsAccount = accountCountForCompanyMapper.queryFirstByVGsBm(sysAccountBandDept.getvGsBm());
            if (logisticsAccount == null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("物流公司实时资金不存在,请核实后再操作!");
            }
//                     运营公司
            operationAccount = accountCountForCompanyMapper.queryFirstByVGsBm(fbaSpellTicket.getCodeCompany());
            if (operationAccount == null) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("运营公司实时资金不存在,请核实后再操作!");
            }
            //资金流水(物流部 -运营公司头程物流费)
            account = new AccountDetailedForCompany();
            account.setGuid(RandomValueUtils.getGUID());
            account.setvGsBm(operationAccount.getvGsBm());
            account.setvGsMc(operationAccount.getvGsMc());
            account.setvGsJc(operationAccount.getvGsJc());
            account.setvGsBmP(logisticsAccount.getvGsBm());
            account.setvGsMcP(logisticsAccount.getvGsMc());
            account.setvGsJcP(logisticsAccount.getvGsJc());
            account.setvJyLx("物流服务→头程运费");
            account.setfJe(-Double.valueOf((fbaSpellTicket.getActualLogisticsFreightPf().subtract(fbaSpellTicket.getActualLogisticsFreight()).toString())));
            account.setdJySj(fbaSpellTicket.getCreateTime());
            account.setdShSj(new Date());
            account.setvBz("头程物流抛货补收费用"+",头程计划单:" + fbaSpellTicket.getCodePlan() + "," + fbaSpellTicket.getShipmentId()+"," + fbaSpellTicket.getNameLogsticsWay()+"," + fbaSpellTicket.getBid());
            account.setCreateTime(new Date());
            accountList.add(account);

            //资金流水(物流部 -运营公司头程物流费)
            account1 = new AccountDetailedForCompany();
            account1.setGuid(RandomValueUtils.getGUID());
            account1.setvGsBm(logisticsAccount.getvGsBm());
            account1.setvGsMc(logisticsAccount.getvGsMc());
            account1.setvGsJc(logisticsAccount.getvGsJc());
            account1.setvGsBmP(operationAccount.getvGsBm());
            account1.setvGsMcP(operationAccount.getvGsMc());
            account1.setvGsJcP(operationAccount.getvGsJc());
            account1.setvJyLx("物流服务→头程运费");
            account1.setfJe(Double.valueOf((fbaSpellTicket.getActualLogisticsFreightPf().subtract(fbaSpellTicket.getActualLogisticsFreight()).toString())));
            account1.setdJySj(fbaSpellTicket.getCreateTime());
            account1.setdShSj(new Date());
            account1.setvBz("头程物流抛货补收费用"+",头程计划单:" + fbaSpellTicket.getCodePlan() + "," + fbaSpellTicket.getShipmentId()+"," + fbaSpellTicket.getNameLogsticsWay()+"," + fbaSpellTicket.getBid());
            account1.setCreateTime(new Date());
            accountList.add(account1);
        }

        businessMapper.insertBatchNew(accountList);


        // 批量新赠物流订单详情
        fbaLogsticsOrderDetailMapper.batchInsert(fbaLogsticsOrderDetailList);
        // 批量新赠物流订单箱子数据
        fbaLogsticsOrderBoxMapper.batchInsert(fbaLogsticsOrderBoxList);
        // 批量修改物流拼票的数据
        fbaSpellTickMapper.batchUpdate(fbaSpellTicketList);
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"),resGuid);
    }


    /**
     * 回退
     * @param params
     * @return
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult htbtn(Map<String, Object> params) {
        List<FbaSpellTicket> fbaSpellTicketList =  JSON.parseArray(params.get("infoItems").toString(), FbaSpellTicket.class);
        List<String> ids = new ArrayList<>();
        List<FbaBox> fbaBoxList = new ArrayList<>();
        FbaBox fbaBox;
        for (FbaSpellTicket fbaSpellTicket : fbaSpellTicketList){
            ids.add(fbaSpellTicket.getGuid());
            fbaBox = new FbaBox();
            fbaBox.setCode(fbaSpellTicket.getCode());
            fbaBox.setStateTrack("0");
            fbaBox.setStateTrackName("无");
            fbaBoxList.add(fbaBox);
        }
        //删除拼票信息
        fbaSpellTickMapper.deleteByIds(ids);
        //删除拼票详情
        fbaSpellTicketDetailMapper.deleteByIds(ids);
        // 批量修改头程装箱数据的发货状态
        fbaBoxMapper.updateBatchCode(fbaBoxList);
        return AjaxResult.success("回退成功");
    }

    /**
     * 查询拼票预测数据
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public FbaSpellTicket queryTicketPooling(Map<String, Object> params) {
        String guidList = String.valueOf(params.get("guidList"));
        String[] guidListSplit = guidList.split(",");
        params.put("guidListSplit",guidListSplit);
        List<FbaSpellTicket> fbaSpellTicketList = fbaSpellTickMapper.select(params);

        //根据主表的guid查询对应箱子所以信息
        List<FbaSpellTicketDetail> fbaSpellTicketDetail = fbaSpellTicketDetailMapper.findFbaSpellTicketDetail(params);

        FbaSpellTicket fbaSpellTicketNew = new FbaSpellTicket();
        List<FbaSpellTicketDetail> fbaSpellTicketDetailNew;
        List<FbaSpellTicketDetail> fbaSpellTicketDetailOld;
        //品名数量
        Set<String> gradeNum = new HashSet<>();
        //重新计算每个fba箱子数据
        for (FbaSpellTicket fbaSpellTicket : fbaSpellTicketList){
            fbaSpellTicketDetailNew = fbaSpellTicketDetail.stream().filter(fbaSpellTicketDeta -> fbaSpellTicketDeta.getFbaSpellTicketGuid().equals(fbaSpellTicket.getGuid())).collect(Collectors.toList());
            //实际的商品信息
            fbaSpellTicketDetailOld = JSON.parseArray(fbaSpellTicketDetailNew.get(0).getProductInfo(), FbaSpellTicketDetail.class);
            for (FbaSpellTicketDetail fbaSpellTicketDetail1 : fbaSpellTicketDetailOld) {
                String join = fbaSpellTicketDetail1.getNameGoodsCn() + '-' + fbaSpellTicketDetail1.getCodeGoodsHs() + '-' + fbaSpellTicketDetail1.getNameMaterialCn();
                gradeNum.add(join);
            }
            //实重合计
            fbaSpellTicketNew.setWeightReal(fbaSpellTicketNew.getWeightReal() == null?fbaSpellTicket.getWeightReal():fbaSpellTicketNew.getWeightReal().add(fbaSpellTicket.getWeightReal()));
            //抛重合计
            fbaSpellTicketNew.setWeightVol(fbaSpellTicketNew.getWeightVol() == null?fbaSpellTicket.getWeightVol():fbaSpellTicketNew.getWeightVol().add(fbaSpellTicket.getWeightVol()));
            //箱数
            fbaSpellTicketNew.setNumBox(fbaSpellTicketNew.getNumBox() == null?fbaSpellTicket.getNumBox():fbaSpellTicketNew.getNumBox()  + fbaSpellTicket.getNumBox());
        }
        //品名数
        fbaSpellTicketNew.setNumProName(gradeNum.size());
        //抛货值
        fbaSpellTicketNew.setJettisonCoe(fbaSpellTicketNew.getWeightVol().subtract(fbaSpellTicketNew.getWeightReal()));
        //平均单箱重
        fbaSpellTicketNew.setAveBoxWeight(fbaSpellTicketNew.getWeightReal().divide(new BigDecimal(fbaSpellTicketNew.getNumBox()),2, RoundingMode.HALF_UP));
        return fbaSpellTicketNew;
    }

    /**
     * 查询拼票预测子件预测数据
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public Set<FbaSpellTicketDetail> queryTicketPoolingDetail(Map<String, Object> params) {
        String guidList = String.valueOf(params.get("guidList"));
        String[] guidListSplit = guidList.split(",");
        params.put("guidListSplit",guidListSplit);
        List<FbaSpellTicket> fbaSpellTicketList = fbaSpellTickMapper.select(params);

        //根据主表的guid查询对应箱子所以信息
        List<FbaSpellTicketDetail> fbaSpellTicketDetail = fbaSpellTicketDetailMapper.findFbaSpellTicketDetail(params);

        List<FbaSpellTicketDetail> fbaSpellTicketDetailNew;
        List<FbaSpellTicketDetail> fbaSpellTicketDetailOld;
        Set<FbaSpellTicketDetail> fbaSpellTicketDetailList = new LinkedHashSet<>();
        Set<String> productBases = new HashSet<>();
        //重新计算每个fba箱子数据
        for (FbaSpellTicket fbaSpellTicket : fbaSpellTicketList){
            fbaSpellTicketDetailNew = fbaSpellTicketDetail.stream().filter(fbaSpellTicketDeta -> fbaSpellTicketDeta.getFbaSpellTicketGuid().equals(fbaSpellTicket.getGuid())).collect(Collectors.toList());
            //实际的商品信息
            fbaSpellTicketDetailOld = JSON.parseArray(fbaSpellTicketDetailNew.get(0).getProductInfo(), FbaSpellTicketDetail.class);
            for (FbaSpellTicketDetail fbaSpellTicketDetail1 : fbaSpellTicketDetailOld) {
                fbaSpellTicketDetailList.add(fbaSpellTicketDetail1);
                productBases.add(fbaSpellTicketDetail1.getCommodityCode());
            }
        }

        List<ProductBasis> productActiveBatchList  = productBasisMapper.findOnlineStoreProductsBatch(productBases);
        List<ProductBasis> productActiveBatchListNew;
        //赋值图片
        for (FbaSpellTicketDetail fbaSpellTicketDetail1 : fbaSpellTicketDetailList) {
            productActiveBatchListNew = productActiveBatchList.stream().filter(
                    productBasis -> productBasis.getCode().equals(fbaSpellTicketDetail1.getCommodityCode())).collect(Collectors.toList());
            if (productActiveBatchListNew.size() != 0){
                fbaSpellTicketDetail1.setImg(productActiveBatchListNew.get(0).getImg());
            }
        }

        return fbaSpellTicketDetailList;
    }

    private BigDecimal precision(BigDecimal f){
        //根据数字未满5满5,未满10满10
        String s = f.stripTrailingZeros().toPlainString();
        String ff = f.toString();
        int rs = s.indexOf(".");
        if (rs != -1) {
            //取出第一位
            String first = s.substring(0,rs);
            //根据第一位小数5来判断，大于0.5以上进1,小于0.5的为0.5
            first = first + ".5";
            Double fD = Double.parseDouble(String.valueOf(f));
            Double firstD = Double.parseDouble(first);
            if (fD < firstD){
                ff = first;
            } else if(fD > firstD) {
                ff = String.valueOf(Math.round(fD));
            }
        }
        return new BigDecimal(ff);
    }
}
